package com.weixin.gong.utils.http;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import com.weixin.gong.utils.NullUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.text.MessageFormat;
import java.util.Map;

/**
 * @author weixin.gong
 * @date 15-11-3 上午11:25
 */
public class HttpUtil {

    private static final Logger LOGGER = LoggerFactory.getLogger(HttpUtil.class);

    private static final int connectTimeout = 100000;
    private static final int requestTimeout = 100000;
    private static final int socketTimeout = 150000;

    private static final HttpClient httpClient;

    static {
        RequestConfig defaultRequestConfig = RequestConfig.custom().setConnectionRequestTimeout(requestTimeout)
                .setSocketTimeout(socketTimeout).setConnectTimeout(connectTimeout).setExpectContinueEnabled(false)
                .build();
        httpClient = HttpClients.custom().setDefaultRequestConfig(defaultRequestConfig)
                .setMaxConnTotal(200).build();
    }

    public static String sendGet(String url) throws IOException {
        return send(new HttpGet(url));
    }

    public static String sendGet(String url, Map<String, String> header) throws IOException {
        HttpGet request = new HttpGet(url);
        header = NullUtil.nullToEmpty(header);
        for (Map.Entry<String, String> entry : header.entrySet()) {
            request.setHeader(entry.getKey(), entry.getValue());
        }
        return send(request);
    }

    private static String send(HttpGet request) throws IOException {
        long start = System.currentTimeMillis();
        try {
            HttpResponse response = httpClient.execute(request);
            HttpEntity entity = response.getEntity();
            String result = EntityUtils.toString(entity, "UTF-8");
            LOGGER.info("method:get, time:{}, req:{}, result:{}", System.currentTimeMillis() - start,
                    request.getURI(), result);
            return result;
        } catch (IOException e) {
            throw new IOException(MessageFormat.format("method:get, time:{0}, req:{1}",
                    System.currentTimeMillis() - start, request.getURI()), e);
        }
    }

    public static String sendPostJson(String url, Map<String, Object> param,
            Map<String, String> header) throws IOException {
        try {
            param = NullUtil.nullToEmpty(param);
            header = NullUtil.nullToEmpty(header);
            HttpPost request = new HttpPost(url);
            request.addHeader("content-type", "application/json");
            for (Map.Entry<String, String> entry : header.entrySet()) {
                request.setHeader(entry.getKey(), entry.getValue());
            }
            StringEntity params = new StringEntity(JSONObject.toJSONString(param), "UTF-8");
            request.setEntity(params);
            long start = System.currentTimeMillis();
            HttpResponse response = httpClient.execute(request);
            HttpEntity entity = response.getEntity();
            String result = EntityUtils.toString(entity, "UTF-8");
            LOGGER.info("method:post, time:{}, req:{}, param:{}, header:{}, result:{}",
                    System.currentTimeMillis() - start, url, param, header, result);
            if (StringUtils.isBlank(result)) {
                String exception = MessageFormat.format("post req:{0}, param:{1}, header:{2}, response is blank",
                        url, param, header);
                throw new IOException(exception);
            }
            return result;
        } catch (IOException e) {
            throw new IOException(MessageFormat.format("post req:{0}, param:{1}, header:{2}", url, param, header), e);
        }
    }

    public static String sendPostJson(String url, Map<String, Object> param) throws IOException {
        return sendPostJson(url, param, Maps.<String, String>newHashMap());
    }
}
